<?php


namespace app\controller\api;


use app\BaseController;
use app\common\exception\ApiException;
use app\model\cart\CheckCartReportRecordModel;
use app\model\cart\VerifyCartComplaintModel;
use app\model\cart\VerifyCartMenuModel;
use app\model\cart\VerifyCartModel;
use app\model\cart\VerifyCartShapeModel;
use app\model\coach\UserCoachModel;
use app\model\config\RegionModel;
use app\model\goods\OrderModel;
use app\model\partner\EscortMenuModel;
use app\model\partner\EscortMenuOrderModel;
use app\model\partner\EscortMenuReserveOrderModel;
use app\model\partner\UserPartnerModel;
use app\model\user\UserCouponModel;
use app\model\user\UserModel;
use app\service\config\ConfigService;
use app\service\order\PartnerOrderService;
use app\service\order\VerifyOrderService;
use app\service\user\UserCouponService;
use app\service\user\UserService;
use app\service\utils\LockService;
use app\service\utils\QqMapService;
use app\service\utils\QrcodeService;
use app\service\utils\WeiXinPayService;
use app\validate\cart\VerifyCartValidate;
use GuzzleHttp\Exception\GuzzleException;
use think\facade\Db;
use think\facade\Queue;

class VerifyCartController extends BaseController
{

    /**
     * 车型列表
     * @return \think\response\Json
     */
    public function getCatShapeList()
    {
        try {
            $list = VerifyCartShapeModel::field('id,title')->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 套餐列表
     * @return \think\response\Json
     */
    public function getMenuList()
    {
        try {
            $type = $this->request->param('type', 0);
            $list = EscortMenuModel::where('type', $type)->where('menu_type', 2)->where('status', 1)->order('sort', 'desc')->select();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 提交验车信息
     * @return \think\response\Json
     */
    public function submitCart()
    {
        Db::startTrans();
        try {
            $userId = $this->request->middleware('userId');

            $data = $this->request->only(['menu_id', 'brand', 'cart_type', 'condition', 'mobile', 'name', 'time', 'lng', 'lat', 'address'], 'param', 'trim');

            Validate(VerifyCartValidate::class)->check($data);

            // 教练可得金额
            $menuInfo = EscortMenuModel::find($data['menu_id']);
            if (!$menuInfo) {
                throw new ApiException('套餐不存在');
            }
            $qqMapService = new QqMapService();
            $info = $qqMapService->getAddressInfo($data['lng'], $data['lat']);
            $adcode = $info['ad_info']['adcode'];
            $regionInfo = RegionModel::where('id', $adcode)->find();
            if ($regionInfo['level'] == 3) {
                $cityId = $regionInfo['pid'];
            } else {
                $cityId = $adcode;
            }
            $orderSn = createOrderSn('order', 'order_sn', 'YC');

            $orderModel = new OrderModel();
            $orderModel->order_sn = $orderSn;
            $orderModel->order_type = 1;
            $orderModel->user_id = $userId;
            $orderModel->mobile = $data['mobile'];
            $orderModel->city_id = $cityId;
            $orderModel->reserve_time = strtotime($data['time']);
            $orderModel->save();

            $escortMenuOrderModel = new EscortMenuOrderModel();
            $escortMenuOrderModel->order_type = 2;
            $escortMenuOrderModel->user_id = $userId;
            $escortMenuOrderModel->menu_id = $data['menu_id'];
            $escortMenuOrderModel->amount = $menuInfo['price'];
            $escortMenuOrderModel->coach_amount = $menuInfo['amount'];
            $escortMenuOrderModel->order_sn = $orderSn;
            $escortMenuOrderModel->city_id = $cityId;
            $escortMenuOrderModel->menu_price = $menuInfo['price'];
            $escortMenuOrderModel->menu_name = $menuInfo['name'];
            $escortMenuOrderModel->menu_old_price = $menuInfo['price'];
            $escortMenuOrderModel->menu_image = $menuInfo['image'];
            $escortMenuOrderModel->save();


            // 添加预约单
            $escortMenuReserveOrderModel = new EscortMenuReserveOrderModel();
            $escortMenuReserveOrderModel->order_type = 2;
            $escortMenuReserveOrderModel->order_sn = $orderSn;
            $escortMenuReserveOrderModel->city_id = $cityId;
            $escortMenuReserveOrderModel->order_id = $escortMenuOrderModel->id;
            $escortMenuReserveOrderModel->menu_id = $data['menu_id'];
            $escortMenuReserveOrderModel->user_id = $userId;
            $escortMenuReserveOrderModel->username = $data['name'];
            $escortMenuReserveOrderModel->mobile = $data['mobile'];
            $escortMenuReserveOrderModel->lng = $data['lng'];
            $escortMenuReserveOrderModel->lat = $data['lat'];
            $escortMenuReserveOrderModel->address = $data['address'];
            $escortMenuReserveOrderModel->condition = $data['condition'];
            $escortMenuReserveOrderModel->reserve_time = strtotime($data['time']);
            $escortMenuReserveOrderModel->reserve_type = 1;
            $escortMenuReserveOrderModel->brand = $data['brand'];
            $escortMenuReserveOrderModel->cart_type = $data['cart_type'];
            $escortMenuReserveOrderModel->delete_time = 1;
            $escortMenuReserveOrderModel->save();

            Db::commit();
            return $this->success($orderSn);
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception);
        }
    }

    /**
     *订单可用优惠券
     * @return \think\response\Json
     */
    public function getVerifyCartOrderCouponList()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderSn = $this->request->param('order_sn', '', 'trim');
            $orderInfo = EscortMenuOrderModel::where('order_sn', $orderSn)->find();
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['user_id'] != $userId) {
                throw new ApiException('非法请求');
            }
            $userCouponService = new UserCouponService();
            $list = $userCouponService->getOrderCouponList($userId, $orderInfo['price'], 2);
            return $this->success(['total' => count($list), 'list' => $list]);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 订单支付
     * @return \think\response\Json
     */
    public function payVerifyCartOrder()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderSn = $this->request->param('order_sn', '', 'trim');
            $userCouponId = $this->request->param('user_coupon_id', 0, 'int');
            $payType = $this->request->param('pay_type', 0, 'int');
            if (!$orderSn) {
                throw new ApiException('订单号错误');
            }
            if (!$payType) {
                throw new ApiException('请选择支付类型');
            }
            $orderInfo = EscortMenuOrderModel::where('order_sn', $orderSn)->find();
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['user_id'] != $userId) {
                throw new ApiException('非法请求');
            }
            if ($orderInfo['pay_status'] !== 1) {
                throw new ApiException('订单状态错误');
            }
            $orderAmount = $orderInfo['amount'];
            $couponAmount = 0;
            if ($userCouponId) {
                $couponAmount = UserCouponModel::where('id', $userCouponId)->where('user_id', $userId)->value('amount', 0);
            }
            $payAmount = $orderAmount - $couponAmount;
            if ($payAmount <= 0) {
                throw new ApiException('支付金额错误');
            }

            $orderInfo->pay_amount = $payAmount;
            $orderInfo->pay_type = $payType;
            $orderInfo->user_coupon_id = $userCouponId;
            $orderInfo->save();

            if ($payType == 2) {
                // 先用后付 直接返回
                throw new ApiException('暂不支持该支付方式');
            }
            $userInfo = UserModel::find($orderInfo['user_id']);
            if (!$userInfo) {
                throw new ApiException('用户不存在');
            }
            $openID = $userInfo['openid'];
            if (!$openID) {
                throw new ApiException('用户未授权登录');
            }
            $service = new WeiXinPayService();
            $notifyUrl = $this->request->domain() . '/api/notify/verifyCartNotify';
            $result = $service->pay($orderSn, $payAmount, $openID, $notifyUrl, '验车订单支付');
            return $this->success($result);
        } catch (\Exception $exception) {
            return $this->error($exception);
        } catch (GuzzleException $e) {
            return $this->error($e);
        }
    }

    /**
     *我的验车列表
     * @return \think\response\Json
     */
    public function getOrderList()
    {
        try {
            $userId = $this->request->middleware('userId');
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 10, 'int');
            // 1待接单 2服务中 3已完成
            $status = $this->request->param('status', 0, 'int');
            $where = [];
            $where[] = ['user_id', '=', $userId];
            $where[] = ['order_type', '=', 2];
            if ($status == 1) {
                $where[] = ['status', '=', 1];
            }
            if ($status == 2) {
                $where[] = ['status', 'in', [3, 4, 7, 8]];
            }
            if ($status == 3) {
                $where[] = ['status', '=', 5];
            }
            $list = EscortMenuReserveOrderModel::with(['source', 'menuOrder'])->where($where)
                ->order('id', 'desc')
                ->paginate(['list_row' => $limit, 'page' => $page])
                ->toArray();
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     *我的验车详情
     * @return \think\response\Json
     */
    public function getOrderDetail()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderId = $this->request->param('order_id', 0, 'int');

            $orderInfo = VerifyCartModel::with(['coach'])->where('id', $orderId)->where('user_id', $userId)->find();
            if (!$orderInfo) {
                throw new ApiException('非法请求');
            }
            $orderInfo = $orderInfo->toArray();

            // 教练
            $coachUserInfo = UserPartnerModel::field('username,mobile,birthday,drive_age')->find($orderInfo['coach_user_id']);
            $orderInfo['coach_user'] = $coachUserInfo;
            return $this->success($orderInfo);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 取消订单
     */
    public function cancelOrder()
    {
        Db::startTrans();
        try {
            $userId = $this->request->middleware('userId');
            $orderId = $this->request->param('order_id', 0, 'int');

            $orderInfo = EscortMenuReserveOrderModel::where('id', $orderId)->where('user_id', $userId)->find();
            if (!$orderInfo) {
                throw new ApiException('非法请求');
            }
            if ($orderInfo['status'] != 1) {
                throw new ApiException('待服务订单才能取消');
            }
            if ($orderInfo['source_id'] != 1) {
                throw new ApiException('仅支持平台订单退款');
            }
            $orderInfo->status = 6;
            $orderInfo->save();

            // 取消套餐订单
            $menuOrderInfo = EscortMenuOrderModel::where('id', $orderInfo['order_id'])->find();
            $amount = 0;
            if ($menuOrderInfo) {
                $menuOrderInfo->pay_status = 4;
                $menuOrderInfo->save();
                $amount = $menuOrderInfo['pay_amount'];
            }

            if ($menuOrderInfo['pay_type'] == 1 && $amount > 0) {
                // 微信退款
                $weiXinPayService = new WeiXinPayService();
                $weiXinPayService->refund($orderInfo['order_sn'], intval($amount * 100));
            }
            // 套餐销量
            $menuInfo = EscortMenuModel::where('id', $menuOrderInfo['menu_id'])->find();
            if ($menuInfo) {
                $menuInfo->sale_num = Db::raw('sale_num-1');
                $menuInfo->save();
            }

            $orderModel = OrderModel::where('order_sn', $orderInfo['order_sn'])->find();
            if ($orderModel) {
                $orderModel->status = -1;
                $orderModel->save();
            }
            Db::commit();
            // 订单取消通知
            Queue::push('WeiXinTemplateMsgJob', ['msg_type' => 'cancel_order', 'id' => $orderId]);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception);
        }
    }

    /**
     * 删除订单
     */
    public function delOrder()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderId = $this->request->param('order_id', 0, 'int');

            $orderInfo = EscortMenuReserveOrderModel::where('id', $orderId)->where('user_id', $userId)->find();
            if (!$orderInfo) {
                throw new ApiException('订单不存在');
            }
            if ($orderInfo['status'] != 4 && $orderInfo['status'] != 1) {
                throw new ApiException('订单状态错误');
            }
            $orderInfo->delete();
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 订单投诉
     */
    public function complaintOrder()
    {
        try {
            $userId = $this->request->middleware('userId');
            $orderId = $this->request->param('order_id', 0, 'int');
            $img = $this->request->param('img', '', 'trim');
            $content = $this->request->param('content', '', 'trim');

            $orderInfo = VerifyCartModel::where('id', $orderId)->where('user_id', $userId)->find();
            if (!$orderInfo) {
                throw new ApiException('非法请求');
            }

            $verifyCartComplaintModel = new VerifyCartComplaintModel();
            $verifyCartComplaintModel->user_id = $userId;
            $verifyCartComplaintModel->order_id = $orderId;
            $verifyCartComplaintModel->coach_user_id = $orderInfo['coach_user_id'];
            $verifyCartComplaintModel->img = $img;
            $verifyCartComplaintModel->content = $content;
            $verifyCartComplaintModel->save();
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }

    /**
     * 完成订单
     */
    public function completeOrder()
    {
        Db::startTrans();
        $userId = $this->request->middleware('userId');
        $orderId = $this->request->param('order_id', 0, 'int');
        $key = sprintf("complete:verify_car:%d", $orderId);
        $lockService = new LockService($key);
        $uniqid = uniqid();
        try {
            if (!$lockService->acquireLockWithoutRetry($uniqid)) {
                throw new ApiException('请勿重复完成');
            }
            VerifyOrderService::completeOrderService($orderId);
            Db::commit();
            $lockService->releaseLock($uniqid);
            return $this->success();
        } catch (\Exception $exception) {
            Db::rollback();
            $lockService->releaseLock($uniqid);
            return $this->error($exception);
        }
    }

    /**
     * 验车结果
     * @return \think\response\Json
     */
    public function result()
    {
        try {
            $orderId = $this->request->param('order_id', 0, 'int');
            $list = CheckCartReportRecordModel::where('order_id', $orderId)->select();
            $remark = $list ? $list[0]['intro'] : '';
            return $this->success(['list' => $list, 'intro' => $remark]);
        } catch (\Exception $exception) {
            return $this->error($exception);
        }
    }
}